package com.rockbb.common.sso.session;

import java.util.ArrayList;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.apache.log4j.Logger;
import org.codehaus.jackson.map.ObjectMapper;

import com.rockbb.common.utilities.internet.Crawler;
import com.rockbb.common.utilities.security.StringDigest;
import com.rockbb.common.utilities.text.JacksonMapper;

public abstract class BasicUserFactory {

	private static Logger logger = Logger.getLogger(BasicUserFactory.class);

	public abstract SessionUser getLocalUserByUUID(long userId);

	public abstract void insertUser(SessionUser sessionUser);

	public SessionUser get(Session session) {
		return get(session, true);
	}

	public SessionUser get(Session session, boolean create) {
		if (session.getSession_uuid() == SessionConstants.USER_UID_ANONYMOUS) {
			return SessionUser.getAnonymousUser();
		}

		SessionUser user = getLocalUserByUUID(session.getSession_uuid());

		if (user == null) {
			user = sync(session);
			if (create || user != null) {
				insertUser(user);
			}
		}

		if (user == null) {
			user= SessionUser.getAnonymousUser();
		}
		return user;
	}

	public static SessionUser sync(Session session) {

		int factory_mode =	SessionConstants.SESSION_MODE;
		if (factory_mode == SessionConstants.FACTORY_MODE_SERVER) {
			return SessionUser.getAnonymousUser();
		}

		String token = StringDigest.md5(SessionConstants.SESSION_CLIENT_TOKEN+session.getSession_ip()+session.getSession_id());

		Crawler httpChannel = new Crawler();
		ArrayList<NameValuePair> nvps = new ArrayList<NameValuePair>();
		nvps.add(new BasicNameValuePair(SessionConstants.PARAM_MODE, String.valueOf(SessionConstants.MODE_USER)));
		nvps.add(new BasicNameValuePair(SessionConstants.PARAM_SID, session.getSession_id()));
		nvps.add(new BasicNameValuePair(SessionConstants.PARAM_IP, session.getSession_ip()));
		nvps.add(new BasicNameValuePair(SessionConstants.PARAM_AGENT, session.getSession_browser()));
		nvps.add(new BasicNameValuePair(SessionConstants.PARAM_TOKEN_HASH, token));
		nvps.add(new BasicNameValuePair(SessionConstants.PARAM_KEY, SessionConstants.SESSION_CLIENT_KEY));

		String echo = httpChannel.post(SessionConstants.SESSION_SYNC_ADDR, nvps);

		SessionUser user = null;
		if(echo != null && echo.length() > 6) {
			ObjectMapper mapper = JacksonMapper.getInstance();
			try {
				echo = StringDigest.base64ToString(echo);
				user = mapper.readValue(echo, new SessionUser().getClass());

			} catch(Exception e) {
				logger.info("Exceptions in fetching user data. Client:" + SessionConstants.SESSION_CLIENT_KEY);
				user = null;
			}
		} else {
			logger.info("Failed to fetch user data. Client:" + SessionConstants.SESSION_CLIENT_KEY);
		}

		return user;
	}

}